package com.jxpanda.infrastructure.core.tollkit;

import lombok.RequiredArgsConstructor;

import java.util.Random;
import java.util.function.Supplier;

/**
 * 随机工具
 *
 * @author Panda
 */
@SuppressWarnings("UnusedReturnValue")
public class RandomKit {

    private static final int USUAL_DIGIT = 6;
    private static final String RANDOM_CHARACTERS_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    private static final String RANDOM_CHARACTERS_NUMBERS = "0123456789";
    private static final String RANDOM_CHARACTERS_ALPHABETIC = RANDOM_CHARACTERS_LETTERS + RANDOM_CHARACTERS_NUMBERS;
    private static final String RANDOM_CHARACTERS_SPECIAL_CHARS = "!@#$%^&*()_+-=[]{}|;:,.<>?";
    private static final String RANDOM_CHARACTERS_ALL = RANDOM_CHARACTERS_ALPHABETIC + RANDOM_CHARACTERS_SPECIAL_CHARS;

    public static String randomAlphabetic() {
        return randomAlphabetic(USUAL_DIGIT);
    }

    public static String randomAlphabetic(int digit) {
        return randomCharacters(CharactersType.ALPHABETIC, digit);
    }


    public static String randomNumeric() {
        return randomNumeric(USUAL_DIGIT);
    }


    public static String randomNumeric(int digit) {
        return randomCharacters(CharactersType.NUMBERS, digit);
    }


    /**
     * 返回6位数随机整数
     * 默认6位比较常用，这里给一个快捷方式
     */
    public static int randomInt() {
        return randomInt(USUAL_DIGIT);
    }

    /**
     * 返回随机的整型随机数
     * 这个函数和randomNumeric的区别是返回值是int类型，不是String类型
     */
    public static int randomInt(int digit) {
        return Integer.parseInt(randomNumeric(digit));
    }


    /**
     * 返回double类型的随机数
     */
    public static double randomDouble() {
        return new Random().nextDouble();
    }

    public static int randomIntRange(int start, int end) {
        return new Random().nextInt(start, start);
    }

    public static double randomDoubleRange(double start, double end) {
        return new Random().nextDouble(start, end);
    }

    public static String randomCharacters(CharactersType charactersType, int length) {
        charactersType = charactersType == null ? CharactersType.ALL : charactersType;
        String characters = charactersType.getCharacters();
        Random random = new Random();
        StringBuilder result = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            int index = random.nextInt(characters.length());
            result.append(characters.charAt(index));
        }
        return result.toString();
    }


    @RequiredArgsConstructor
    public enum CharactersType {
        LETTERS(() -> RandomKit.RANDOM_CHARACTERS_LETTERS),
        NUMBERS(() -> RandomKit.RANDOM_CHARACTERS_NUMBERS),
        ALPHABETIC(() -> RandomKit.RANDOM_CHARACTERS_ALPHABETIC),
        SPECIAL_CHARS(() -> RandomKit.RANDOM_CHARACTERS_ALPHABETIC),
        ALL(() -> RANDOM_CHARACTERS_ALL);
        private final Supplier<String> characterSupplier;

        private String getCharacters() {
            return characterSupplier.get();
        }
    }

}
